package com.zxy.ziems.server.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zxy.btp.common.exception.ConditionException;
import com.zxy.btp.common.response.PageResult;
import com.zxy.btp.common.util.JsonUtils;
import com.zxy.ziems.server.convert.AgreementChannelConvert;
import com.zxy.ziems.server.convert.ChannelEquipConvert;
import com.zxy.ziems.server.domain.Agreement;
import com.zxy.ziems.server.domain.AgreementChannel;
import com.zxy.ziems.server.domain.ChannelEquip;
import com.zxy.ziems.server.domain.ChannelField;
import com.zxy.ziems.server.domain.EquipPointRel;
import com.zxy.ziems.server.domain.FieldValue;
import com.zxy.ziems.server.domain.User;
import com.zxy.ziems.server.dto.AgreementChannelDto;
import com.zxy.ziems.server.dto.AgreementChannelQueryDto;
import com.zxy.ziems.server.dto.ChannelEquipDto;
import com.zxy.ziems.server.dto.ChannelEquipQueryDto;
import com.zxy.ziems.server.mapper.AgreementChannelMapper;
import com.zxy.ziems.server.mapper.ChannelEquipMapper;
import com.zxy.ziems.server.mapper.EquipPointRelMapper;
import com.zxy.ziems.server.service.ChannelEquipService;
import com.zxy.ziems.server.service.ChannelFieldService;
import com.zxy.ziems.server.service.FieldValueService;
import com.zxy.ziems.server.service.UserService;
import com.zxy.ziems.server.vo.AgreementChannelVo;
import com.zxy.ziems.server.vo.ChannelEquipVo;
import com.zxy.ziems.server.vo.FieldValueVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName ChannelEquipServiceImpl
 * @Description
 * @Author 邓伟
 * @Date 2023/11/29 15:55
 * @Version 1.0
 */
@Service
public class ChannelEquipServiceImpl extends ServiceImpl<ChannelEquipMapper, ChannelEquip> implements ChannelEquipService {


    @Autowired
    private ChannelEquipMapper channelEquipMapper;
    @Autowired
    private UserService userService;
    @Autowired
    private FieldValueService fieldValueService;
    @Autowired
    private EquipPointRelMapper equipPointRelMapper;
    @Autowired
    private AgreementChannelMapper agreementChannelMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addOrUpdate(ChannelEquipDto channelEquipDto) {
        checkCode(channelEquipDto);
        String equipId = channelEquipDto.getEquipId();
        ChannelEquip channelEquip = ChannelEquipConvert.INSTANCE.channelEquipDtoToChannelEquip(channelEquipDto);
        if (StrUtil.isEmpty(equipId)) {
            channelEquipMapper.insert(channelEquip);
        }else {
            channelEquipMapper.updateById(channelEquip);
        }
        //保存参数信息
        fieldValueService.batchInsert(channelEquip.getChannelId(),channelEquip.getEquipId(),channelEquip.getEquipCode(),channelEquipDto.getFieldValueDtoList());
    }

    @Override
    public void delete(String equipId) {
        //判断是否有绑定的点位
        QueryWrapper<EquipPointRel> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(EquipPointRel::getEquipId,equipId);
        Long count = equipPointRelMapper.selectCount(queryWrapper);
        if (count > 0) {
            throw new ConditionException("设备下有绑定的点位，不允许删除");
        }
        removeById(equipId);
        //删除设备参数信息
        QueryWrapper<FieldValue> query = new QueryWrapper<>();
        query.lambda().eq(FieldValue::getDataId,equipId);
        fieldValueService.remove(query);
    }

    @Override
    public PageResult<ChannelEquipVo> pageList(ChannelEquipQueryDto queryDto) {
        //组装wrapper
        QueryWrapper<ChannelEquip> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().like(ObjectUtil.isNotEmpty(queryDto.getEquipCode()),ChannelEquip::getEquipCode,queryDto.getEquipCode());
        queryWrapper.lambda().orderByDesc(ChannelEquip::getUpdateTime);
        Page<ChannelEquip> page = channelEquipMapper.selectPage(new Page<>(queryDto.getPageNo(), queryDto.getPageSize()), queryWrapper);
        List<ChannelEquip> records = page.getRecords();
        //空值
        if (ObjectUtil.isEmpty(records)){
            return new PageResult<>(page.getTotal(), Collections.emptyList());
        }
        //查询通道信息
        List<String> channelIdList = records.stream().map(ChannelEquip::getChannelId).toList();
        Map<String,AgreementChannel> channelMap = new HashMap<>();
        if (CollectionUtil.isNotEmpty(channelIdList)){
            List<AgreementChannel> channelList = agreementChannelMapper.selectBatchIds(channelIdList);
            channelMap = channelList.stream().collect(Collectors.toMap(AgreementChannel::getChannelId,v1->v1));
        }

        List<String> userIdList = records.stream().map(ChannelEquip::getUpdateUserId).toList();
        //负责人
        Map<String,String> userMap = new HashMap<>();
        if (CollectionUtil.isNotEmpty(userIdList)){
            List<User> userList = userService.listByIds(userIdList);
            userMap = userList.stream().collect(Collectors.toMap(User::getUserId,User::getUserName));
        }
        //查询参数信息
        List<String> equipIdList = records.stream().map(ChannelEquip::getEquipId).toList();
        List<FieldValueVo> channelFieldList = fieldValueService.selectList(equipIdList);
        Map<String, Map<String, String>> map = channelFieldList.stream().collect(Collectors.groupingBy(FieldValueVo::getDataId, Collectors.toMap(FieldValueVo::getFieldName, FieldValueVo::getFieldValue)));
        List<ChannelEquipVo> voList = new ArrayList<>();
        for (ChannelEquip channelEquip : records) {
            ChannelEquipVo channelEquipVo = ChannelEquipConvert.INSTANCE.channelEquipToChannelEquipVo(channelEquip);
            channelEquipVo.setUpdateUserName(userMap.get(channelEquipVo.getUpdateUserId()));
            channelEquipVo.setChannelName(channelMap.get(channelEquipVo.getChannelId()).getChannelName());
            channelEquipVo.setChannelType(channelMap.get(channelEquipVo.getChannelId()).getChannelType());
            //处理参数
            Map<String, String> paramMap = map.get(channelEquipVo.getEquipId());
            channelEquipVo.setParamStr(JsonUtils.toJSONString(paramMap));

            voList.add(channelEquipVo);
        }
        return new PageResult<>(page.getTotal(),voList);
    }

    @Override
    public ChannelEquipVo detail(String equipId) {
        ChannelEquip channelEquip = channelEquipMapper.selectById(equipId);
        ChannelEquipVo channelEquipVo = ChannelEquipConvert.INSTANCE.channelEquipToChannelEquipVo(channelEquip);
        //查询关联参数信息
        List<FieldValueVo> fieldValueVoList = fieldValueService.selectList(List.of(equipId));
        channelEquipVo.setFieldList(fieldValueVoList);
        return channelEquipVo;
    }

    private void checkCode(ChannelEquipDto channelEquipDto) {
        String equipCode = channelEquipDto.getEquipCode();
        String equipId = channelEquipDto.getEquipId();
        QueryWrapper<ChannelEquip> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ChannelEquip::getEquipCode,equipCode);
        if (StrUtil.isNotEmpty(equipId)) {
            queryWrapper.lambda().ne(ChannelEquip::getEquipId,equipId);
        }
        Long count = channelEquipMapper.selectCount(queryWrapper);
        if (count > 0) {
            throw new ConditionException("设备编码不能重复，请修改后再保存");
        }
    }
}
